﻿#pragma once
namespace LK
{
	namespace Drawing
	{
		/**@brief 表示一个2D坐标点，T表示坐标数据的类型，比如int、float等*/
		template<class T>class Point
		{
		public:
			/**@brief x坐标*/
			T x;
			/**@brief y坐标*/
			T y;
			/**@brief 默认构造*/
			Point(){}
			/**@brief 使用2个坐标值构造*/
			Point(T const& x, T const& y) : x(x), y(y){}
			/**@brief 使用其它类型的坐标构造*/
			template<class OT>inline Point(const Point<OT>& p) : x(p.x), y(p.y){}
			/**@brief 坐标正偏移*/
			inline friend Point operator+(const Point & p1, const Point & p2){ return Point(p1.x + p2.x, p1.y + p2.y); }
			inline Point & operator+=(const Point & p){ return *this = *this + p; }
			inline Point operator + (){ return *this; }
			/**@brief 坐标负偏移*/
			inline friend Point operator-(const Point & p1, const Point & p2){ return Point(p1.x - p2.x, p1.y - p2.y); }
			Point & operator-=(const Point & p){ return *this = *this - p; }
			inline Point operator - (){ return Point(-x, -y); }
			/**@brief 坐标乘*/
			inline friend Point operator*(const Point & p, const T & i){ return Point(p.x*i, p.y*i); }
			Point & operator*=(const T & i){ return *this = *this * i; }
			/**@brief 坐标除*/
			inline friend Point operator/(const Point & p, const T & i){ return Point(p.x / i, p.y / i); }
			Point & operator/=(const T & i){ return *this = *this / i; }
			/**@brief 比较*/
			bool operator==(Point const&p)const{ return x == p.x&&y == p.y; }
			bool operator!=(Point const&p)const{ return x != p.x || y != p.y; }
		};
		/**@brief 表示一个3D坐标点，T表示坐标数据的类型，比如int、float等*/
		template<class T>class Point3D
		{
		public:
			/**@brief x坐标*/
			T x;
			/**@brief y坐标*/
			T y;
			/**@brief z坐标*/
			T z;
			/**@brief 默认构造*/
			Point3D(){}
			/**@brief 使用其它类型2D坐标构造*/
			template<class OT>inline Point3D(const Point<OT>& p) : x(p.x), y(p.y), z(0){}
			/**@brief 使用其它类型2D坐标和一个z坐标构造*/
			template<class OT>inline Point3D(const Point<OT>& p, OT const& z) : x(p.x), y(p.y), z(z){}
			/**@brief 使用3个坐标值构造*/
			Point3D(T x = 0, T y = 0, T z = 0) :x(x), y(y), z(z){}
			/**@brief 使用其它类型的坐标构造*/
			template<class oT>inline explicit Point3D(const Point3D<oT>& p) : x(p.x), y(p.y), z(p.z){}
			/**@brief 坐标叠加*/
			inline friend Point3D operator+(const Point3D & p1, const Point3D & p2){ return Point3D(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z); }
			inline Point3D & operator+=(const Point3D & p){ return *this = *this + p; }
			inline Point3D operator + (){ return *this; }
			/**@brief 坐标相减*/
			inline friend Point3D operator-(const Point3D & p1, const Point3D & p2){ return Point3D(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z); }
			Point3D & operator-=(const Point3D & p){ return *this = *this - p; }
			inline Point3D operator - (){ return Point3D(-x, -y, -z); }
			/**@brief 坐标乘*/
			inline friend Point3D operator*(const Point3D & p, const T & i){ return Point3D(p.x*i, p.y*i, p.z*i); }
			Point3D & operator*=(const T & i){ return *this = *this * i; }
			/**@brief 坐标除*/
			inline friend Point3D operator/(const Point3D & p, const T & i){ return Point3D(p.x / i, p.y / i, p.z / i); }
			Point3D & operator/=(const T & i){ return *this = *this / i; }
			/**@brief 比较*/
			bool operator==(Point3D const&p)const{ return x == p.x&&y == p.y&&z == p.z; }
			bool operator!=(Point3D const&p)const{ return x != p.x || y != p.y || z != p.z; }
		};
	}
}